package com.mirror.utils.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.HeaderViewListAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.mirror.llk.R;
import com.mirror.utils.ShortMusicUtils;
import com.mirror.utils.adapter.CustomComplexAdapter;
import com.mirror.utils.base.Page;

public class CustomListView extends ListView {

	private static final String TAG = "CustomListView";

	/** 头部 */
	public View vHead;

	/** 是否包含头部和尾部 */
	private boolean hasHead = true, hasHeadLine = true, hasFoot = true;

	/** 状态 */
	private DragState headState = DragState.NORMAL;

	/** 第一行是否可见 */
	private boolean firstVisible;

	/** 移动是否有效 */
	private boolean isValid;

	/** 起始/结束纵坐标 */
	private int startY, endY;

	/** 头部高 */
	private int headHeight;

	/** 箭头 */
	private ImageView ivArrow;

	/** 进度条 */
	private ProgressBar pbLoading;

	/** 提示/查看更多 */
	private TextView tvMessage, tvMore;

	/** 尾部 */
	public View vFoot, vMore, vHeadLine;

	/** 加载动画 */
	private View vLoading;

	/** 尾部状态 */
	private DragState footState = DragState.NORMAL;

	/** 监听 */
	private OnRefreshLoadListener onRefreshLoadListener;

	/** 动画 */
	private Animation animation, reverseAnimation;

	private Context context;

	private boolean isFristLoading = true;

	private int lastPaddingTop = 0;

	/** 是否分页 */
	private boolean isPaging = false;

	/** 分页参数 */
	private Page page = new Page(0, Integer.MAX_VALUE, Page.OPERATE_NONE, Page.RESULT_NONE);

	/**
	 * 构造方法
	 * 
	 * @param context
	 *            页上下文
	 * @param attrs
	 *            属性
	 */
	@SuppressLint("Recycle")
	public CustomListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		if (attrs != null) {
			TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomListView);
			hasHead = a.getBoolean(R.styleable.CustomListView_hasHead, true);
			hasFoot = a.getBoolean(R.styleable.CustomListView_hasFoot, true);
			hasHeadLine = a.getBoolean(R.styleable.CustomListView_hasHeadLine, true);
			isPaging = a.getBoolean(R.styleable.CustomListView_isPaging, false);
			page = new Page(0, a.getInt(R.styleable.CustomListView_pageSize, isPaging ? 20 : Integer.MAX_VALUE), Page.OPERATE_NONE, Page.RESULT_NONE);
		}
		if (hasHead) {
			// 加载头部
			this.initHeadView(context);
			this.setOnScrollListener(new OnScrollListener() {

				@Override
				public void onScrollStateChanged(AbsListView abslistview, int i) {
				}

				@Override
				public void onScroll(AbsListView abslistview, int i, int j, int k) {
					setFirstVisible(i == 0 ? true : false);
				}
			});
		}
		if (hasFoot) {
			// 加载尾部
			this.intiFootView(context);
		}
	}

	/**
	 * 加载头部
	 * 
	 * @param context
	 *            页上下文
	 */
	private void initHeadView(Context context) {
		this.vHead = LayoutInflater.from(context).inflate(R.layout.list_view_head, null);
		this.addHeaderView(vHead, null, false);
		this.initAnimation();
		this.measureView(vHead);
		this.headHeight = vHead.getMeasuredHeight();
		vHead.setPadding(0, -1 * headHeight, 0, 0);
		this.lastPaddingTop = vHead.getPaddingTop();
		ivArrow = (ImageView) vHead.findViewById(R.id.head_arrowImageView);
		tvMessage = (TextView) vHead.findViewById(R.id.head_tipsTextView);
		pbLoading = (ProgressBar) vHead.findViewById(R.id.head_progressBar);
		vHeadLine = vHead.findViewById(R.id.headLine);
		if (hasHeadLine) {
			vHeadLine.setVisibility(View.VISIBLE);
		} else {
			vHeadLine.setVisibility(View.GONE);
		}
	}

	/**
	 * 初始化尾部
	 * 
	 * @param context
	 *            页上下文
	 */
	private void intiFootView(Context context) {
		vFoot = LayoutInflater.from(context).inflate(R.layout.list_view_foot, null);
		vFoot.setVisibility(GONE);
		vMore = vFoot.findViewById(R.id.load_more_view);
		tvMore = (TextView) vFoot.findViewById(R.id.tv_more);
		vMore.setOnClickListener(moreListener);
		vLoading = (LinearLayout) vFoot.findViewById(R.id.ll_loading);
		addFooterView(vFoot);
	}

	public void load() {
		if (isPaging) {
			onRefreshLoadListener.onRefresh(page.first(Page.OPERATE_REFESH));
		} else {
			onRefreshLoadListener.onRefresh(page.max(Page.OPERATE_REFESH));
		}
	}

	public OnClickListener moreListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			// 防止重复点击
			if (onRefreshLoadListener != null && footState != DragState.LOADING) {
				CustomListView.this.setFootState(DragState.LOADING);
				if (isPaging) {
					onRefreshLoadListener.onLoadMore(page.next(Page.OPERATE_MORE));
				} else {
					onRefreshLoadListener.onLoadMore(null);
				}

			}
		}
	};

	/**
	 * 触屏事件监听
	 */
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		if (hasHead) {
			switch (ev.getAction()) {
				case MotionEvent.ACTION_DOWN:// 按下
					doDown(ev);
					break;
				case MotionEvent.ACTION_MOVE:// 移动
					doMove(ev);
					break;
				case MotionEvent.ACTION_UP:// 抬起
					doUp(ev);
					break;
				default:
					break;
			}
		}
		return super.onTouchEvent(ev);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		return false;
	}

	/**
	 * 触屏操作
	 */
	private void doDown(MotionEvent ev) {
		// 记录起始高
		if (firstVisible && !isValid) {
			this.isValid = true;
			this.startY = (int) ev.getY();
			this.endY = 0;
		}
	}

	/**
	 * 移动操作
	 */
	private void doMove(MotionEvent ev) {
		this.endY = (int) ev.getY();
		if (firstVisible && !isValid) {
			this.startY = (int) ev.getY();
			this.isValid = true;
		}
		if (isValid && headState != DragState.LOADING) {
			int dist = (endY - startY) / 2;
			switch (headState) {
				case NORMAL: {
					if (dist > 0) {
						vHead.setPadding(0, dist - headHeight, 0, 0);
						this.setViewState();
					}
					break;
				}
				case PULL: {
					setSelection(0);
					vHead.setPadding(0, dist - headHeight, 0, 0);
					// if (dist > headHeight) {
					setViewState();
					// }
					break;
				}
				case RELEASE: {
					setSelection(0);
					vHead.setPadding(0, dist - headHeight, 0, 0);
					// if (dist >= 0 && dist <= headHeight) {
					// setViewState();
					// } else if (dist < 0) {
					setViewState();
					// }
					break;
				}
				default:
					return;
			}
		}
	}

	/**
	 * 触屏释放事件
	 * 
	 * @param event
	 *            事件
	 */
	private void doUp(MotionEvent event) {
		isValid = false;
		if (headState == DragState.LOADING) {
			return;
		}
		switch (headState) {
			case PULL: {
				vHead.setPadding(0, -1 * headHeight, 0, 0);
				setViewState();
				break;
			}
			case RELEASE: {
				vHead.setPadding(0, 0, 0, 0);
				onRefresh();
				break;
			}
			case LOADING: {
				vHead.setPadding(0, 0, 0, 0);
				setViewState();
			}
		}

	}

	/**
	 * 更新头部状态
	 * 
	 * @param state
	 *            状态
	 */
	private void setViewLoadingState() {
		pbLoading.setVisibility(View.VISIBLE);
		ivArrow.clearAnimation();
		ivArrow.setVisibility(View.GONE);
		tvMessage.setText("加载中...");
	}

	/**
	 * 更新头部状态
	 * 
	 * @param state
	 *            状态
	 */
	private void setViewState() {
		setViewState(true);
	}

	/**
	 * 更新头部状态
	 * 
	 * @param hasVoice
	 *            是否有声效
	 */
	private void setViewState(boolean hasVoice) {
		int paddingTop = vHead.getPaddingTop();
		if (paddingTop == -headHeight) {
			this.headState = DragState.NORMAL;
			ivArrow.clearAnimation();
			ivArrow.setImageResource(R.drawable.list_view_head_arrow);
		} else if (paddingTop <= 0) {
			if (hasVoice && this.headState == DragState.RELEASE) {
				ShortMusicUtils.playSound(context, 2, 0);
			}
			this.headState = DragState.PULL;
			pbLoading.setVisibility(View.GONE);
			ivArrow.setVisibility(View.VISIBLE);
			ivArrow.clearAnimation();
			ivArrow.startAnimation(getAnimationByPaddingTop());
			tvMessage.setText("下拉可以刷新");
		} else if (paddingTop > 0) {
			if (hasVoice && this.headState == DragState.PULL) {
				ShortMusicUtils.playSound(context, 2, 0);
			}
			this.headState = DragState.RELEASE;
			ivArrow.setVisibility(View.VISIBLE);
			ivArrow.clearAnimation();
			ivArrow.startAnimation(getAnimationByPaddingTop());
			tvMessage.setText("松开可以刷新");
		}
	}

	/**
	 * 刷新
	 */
	private void onRefresh() {
		setViewLoadingState();
		if (onRefreshLoadListener != null) {
			if (isPaging) {
				onRefreshLoadListener.onRefresh(page.first(Page.OPERATE_REFESH));
			} else {
				onRefreshLoadListener.onRefresh(page.max(Page.OPERATE_REFESH));
			}
		}
	}

	/**
	 * 刷新完成更新状态
	 */
	public void onRefreshComplete(int operateResult) {
		vHead.setPadding(0, -1 * headHeight, 0, 0);
		setViewState();
		if (isPaging) {
			switch (operateResult) {
				case Page.RESULT_FULL: {
					// 更新尾部状态
					vFoot.setVisibility(View.VISIBLE);
					vMore.setOnClickListener(moreListener);
					tvMore.setText("查看更多");
					// 更新分页状态
					page.setPageIndex(1);
					page.setOperateType(Page.OPERATE_NONE);
					page.setOperateResult(Page.RESULT_NONE);
					break;
				}
				case Page.RESULT_VACANT: {
					// 更新尾部状态
					vFoot.setVisibility(View.GONE);
					vMore.setOnClickListener(null);
					tvMore.setText("拉取完毕");
					// 更新分页状态
					page.setPageIndex(1);
					page.setOperateType(Page.OPERATE_NONE);
					page.setOperateResult(Page.RESULT_NONE);
					break;
				}
				default:
					break;
			}
		}
	}

	public void onStart(Page page) {
		switch (page.getOperateType()) {
			case Page.OPERATE_REFESH: {
				ListAdapter listAdapter = ((HeaderViewListAdapter) this.getAdapter()).getWrappedAdapter();
				// 刷新
				if (listAdapter instanceof ArrayAdapter) {
					// 清除迭代器缓存
					ArrayAdapter<?> adapter = (ArrayAdapter<?>) listAdapter;
					adapter.clear();
					adapter.notifyDataSetChanged();
				} else if (listAdapter instanceof CustomComplexAdapter) {
					// 清除迭代器缓存
					CustomComplexAdapter adapter = (CustomComplexAdapter) listAdapter;
					adapter.getData().clear();
					adapter.notifyDataSetChanged();
				}
				break;
			}
		}
	}

	public void onComplete(Page page) {
		switch (page.getOperateType()) {
			case Page.OPERATE_REFESH:
				onRefreshComplete(page.getOperateResult());
				break;
			case Page.OPERATE_MORE:
				onMoreComplete(page.getOperateResult());
				break;
		}
		setVisibility(View.VISIBLE);
		if (!isFristLoading) {
			ShortMusicUtils.playSound(context, 3, 0);
		} else {
			isFristLoading = false;
		}
	}

	/**
	 * 设置尾部状态
	 * 
	 * @param footState
	 */
	private void setFootState(DragState footState) {
		switch (footState) {
			case NORMAL: // 普通状态
				vLoading.setVisibility(View.GONE);
				tvMore.setVisibility(View.VISIBLE);
				break;

			case LOADING: // 加载状态
				vLoading.setVisibility(View.VISIBLE);
				tvMore.setVisibility(View.GONE);
				break;
			default:
				break;
		}
		this.footState = footState;
	}

	/**
	 * 点击加载更多
	 */
	public void onMoreComplete(int operateResutl) {
		this.setFootState(DragState.NORMAL);
		if (isPaging) {
			switch (operateResutl) {
				case Page.RESULT_FULL:
					// 更新分页状态
					page.setPageIndex(page.getPageIndex() + 1);
					page.setOperateType(Page.OPERATE_NONE);
					page.setOperateResult(Page.RESULT_NONE);
					break;
				case Page.RESULT_VACANT:
					// 更新尾部状态
					vMore.setOnClickListener(null);
					tvMore.setText("拉取完毕");
					// 更新分页状态
					page.setPageIndex(page.getPageIndex() + 1);
					page.setOperateType(Page.OPERATE_NONE);
					page.setOperateResult(Page.RESULT_NONE);
					break;
				case Page.RESULT_EMPTY:
					// 更新尾部状态
					vMore.setOnClickListener(null);
					tvMore.setText("拉取完毕");
					// 更新分页状态
					page.setOperateType(Page.OPERATE_NONE);
					page.setOperateResult(Page.RESULT_NONE);
				default:
					break;
			}
		}
	}

	/**
	 * 初始化动画
	 */
	private void initAnimation() {
		// 旋转动画
		animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		animation.setInterpolator(new LinearInterpolator());// 匀速
		animation.setDuration(250);
		animation.setFillAfter(true);// 停留在最后状态.
		// 反向旋转动画
		reverseAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		reverseAnimation.setInterpolator(new LinearInterpolator());
		reverseAnimation.setDuration(250);
		reverseAnimation.setFillAfter(true);
	}

	private RotateAnimation getAnimationByPaddingTop() {
		double rate1 = (0 - Math.max(Math.min(this.lastPaddingTop, 0), 0 - this.headHeight * 2d / 3)) * 180d / (this.headHeight * 2d / 3) - 180d;
		double rate2 = (0 - Math.max(Math.min(this.vHead.getPaddingTop(), 0), 0 - this.headHeight * 2d / 3)) * 180d / (this.headHeight * 2d / 3)
		        - 180d;
		this.lastPaddingTop = this.vHead.getPaddingTop();
		// 旋转动画
		RotateAnimation animation = new RotateAnimation((int) rate1, (int) rate2, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
		        RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		animation.setInterpolator(new LinearInterpolator());// 匀速
		animation.setDuration(100);
		animation.setFillAfter(true);// 停留在最后状态.
		return animation;
	}

	/**
	 * 注入监听
	 * 
	 * @param onRefreshLoadListener
	 *            监听
	 */
	public void setOnRefreshLoadListener(OnRefreshLoadListener onRefreshLoadListener) {
		this.onRefreshLoadListener = onRefreshLoadListener;
	}

	/**
	 * 计算头部的宽和高
	 * 
	 * @param child
	 *            视图
	 */
	@SuppressWarnings("deprecation")
	private void measureView(View child) {
		ViewGroup.LayoutParams p = child.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
		}
		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
		int lpHeight = p.height;
		int childHeightSpec;
		if (lpHeight > 0) {
			childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
		} else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
		}
		child.measure(childWidthSpec, childHeightSpec);
	}

	/**
	 * @Title: 拖动效果状态
	 * @Version: 1.0
	 * @Author: QiYin
	 * @Date: 2013-3-1
	 * @Company: EmagSoftware
	 */
	private enum DragState {

		/**
		 * 普通状态
		 */
		NORMAL,

		/**
		 * 下拉状态
		 */
		PULL,

		/**
		 * 松开状态 - 超过高度阀值
		 */
		RELEASE,

		/**
		 * 加载状态
		 */
		LOADING;
	}

	/***
	 * 自定义接口
	 */
	public interface OnRefreshLoadListener {

		/***
		 * 下拉刷新执行
		 */
		void onRefresh(Page page);

		/***
		 * 点击加载更多
		 */
		void onLoadMore(Page page);
	}

	public int getHeadHeight() {
		return headHeight;
	}

	public void setHeadHeight(int headHeight) {
		this.headHeight = headHeight;
	}

	public boolean isFirstVisible() {
		return firstVisible;
	}

	public void setFirstVisible(boolean firstVisible) {
		this.firstVisible = firstVisible;
	}

	public Page getPage() {
		return page;
	}
}
